<?php
namespace control;
/*
*仓库档案类
*/

class warehouseClass extends adIndexClass
{
    private const page = 'warehouse';
    private const table = 'warehouse';
    private const title = '仓库档案';
    private const checkChar = "/(^[a-zA-Z]$)|(^[0-9]{1,2}$)/";//匹配单个字母或两个以下的数字
    private const maxNum = 2000;

    public static function getDepartmentAll($data = []): string
    {
        // 条件
        $data['where'] = $data['where'] ?? "pid='0'";
        // 点击事件
        $data['click'] = $data['click'] ?? "replaceDetail(this,'" . self::page . "')";
        //当前层级
        $data['level'] = isset($data['level'])?$data['level']+1:0;
        // 结果
        $result = find(['table' => 'warehouse_type', 'field' => 'id,name', 'where' => $data['where'] . " and coid = '" . self::$coid . "' order by list asc"]);
        $style = ($data['where'] == "pid='0'" || $data['level'] == 0) ? '' : " class='child-node' data-level='{$data['level']}' ";
        $temp = "<ul {$style} {$data['where']}>";
        $textcontent_ico = "<span class='textcontent_ico'></span>";
        if ($result['array']) {
            foreach ($result['array'] as $value) {
                // 角标
                $arrow = "<span class='arrow'  onclick=\"liZoom($(this).parent())\"></span>";
                // 判断下级是否存在
                $data['where'] = " pid='{$value['id']}' ";
                $has = query('warehouse_type', $data['where']);
                $dots = "<div class='actionBlock none'>
                            <img data-pid='{$value['id']}' title='".lang('material.getDepartmentAll.addSub')."' onclick=\"layer('" . self::page . "','catalog',{id:'" . suiji() . "',pid:'{$value['id']}'})\" src='".root."img/control/list_add.svg'>
                            <img data-id='{$value['id']}' title='".lang('material.getDepartmentAll.edit')."' onclick=\"layer('" . self::page . "','catalog',{id:'" . $value['id'] . "'})\" src='".root."img/control/edit.svg'>
                            <img data-id='{$value['id']}' title='".lang('material.getDepartmentAll.del')."' onclick=\"layer('" . self::page . "','operate',{'act': 'delType',id:'" . $value['id'] . "'})\" src='".root."img/control/list_del.svg'>
                        </div>";
                if ($has['id']) {
                    $temp .= "<li class='arrow-li' data-id='{$value['id']}' onclick=\"{$data['click']}\">
                                {$arrow}
                                <span class='textcontent'>{$textcontent_ico}{$value['name']}</span>
                                <div class='action-div'>{$dots}</div>
                            </li>";
                    $temp .= self::getDepartmentAll($data);
                } else {
                    $temp .= "<li class='arrow-no-li'  data-id='{$value['id']}' onclick=\"{$data['click']}\">
                                <span class='textcontent'>{$textcontent_ico}{$value['name']}</span>
                                <div class='action-div'>{$dots}</div>
                            </li>";
                }
            }
        }
        $temp .= '</ul>';
        return $temp;
    }

    /**
     * 异步加载
     *
     */
    public function homeRightJson(): bool|string
    {
        $json['html'] = $this->homeRight();
        return json_encode($json, 320);
    }

    public function homeRightJsonSearch(): bool|string
    {
        return $this->homeSearch();
    }

    /**
     * 左侧搜索框
     *
     * @return string
     */
    public function getContainerLeftJson(): string
    {
        $option['click'] = 'replaceContent(this, \'warehouse\')';
        $json['html'] = self::getDepartmentAll($option);
        return json_encode($json, 320);
    }


    public function homeHtml(): string
    {
        //返回
        $rightHtml = $this->homeRight();
        $option['click'] = 'replaceContent(this, \'warehouse\')';
        $all = self::getDepartmentAll($option);
        return componentClass::leftNav([
            'searchvalue'=>isset($_SESSION[self::page]['keyword'])?$_SESSION[self::page]['keyword']:'',
            'title'=>'搜索分类',
            'inputOther'=>" onblur=\"typeSession(this,'material','".self::page."')\" ",
            'click'=>$option['click'],
            'edit'=>1,
            'allTitle'=>'全部分类',
            'button'=>"<img class='tool-img' title='添加分类' onclick=\"layer('" . self::page . "','catalog',{id:'" . suiji() . "', pid: 0})\" src='".root."img/control/list_add.svg'>",
            'all'=>$all,
            'rightHtml'=>$rightHtml,
        ]);
    }

    /*列表页-查询条件*/
    public function home()
    {
        //返回
        return $this->homeFun($this->homeHtml());
    }

    public function catalog(): bool|string
    {
        //数据查询
        $info = query(self::table . '_type', " id = '" . $this->post('id') . "' ");
        $pid = $info['pid'] ?: ($this->post('pid') ?: '0');
        //表单
        $html = $this->layerEdit([
            "table" => [
                [
                    must . lang('material.catalog.type')."：" => text(["name" => "name", "value" => $info['name'] ?? null, 'class' => 'text']),
                ],
                [
                    lang('material.catalog.list')."：" => text(["name" => "list", "value" => $info['list'] ?? null, 'class' => 'text']) . hidden(['name' => 'pid', 'value' => $pid]),
                ]
            ]
        ]);
        //返回
        return $this->layer(["title" => lang('material.catalog.edit'), "height" => 220, "html" => $html]);
    }

    public function catalogEdit(): bool|string
    {
        //赋值
        $field = [
            'pid' => $this->post('pid') ?: '0',
            "name" => $this->post('name'),      //部门名称
            "list" => $this->post('list'),      //排序号
        ];
        $info = query(self::table . '_type', " id = '" . $this->post('id') . "' ");
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = lang('material.catalogEdit.power');
        } elseif (empty($field['name'])) {
            $json['warn'] = lang('material.catalogEdit.name');
        } elseif (sqlNum(self::table . '_type', "pid = '$field[pid]' and coid ='" . self::$coid . "' and name = '$field[name]' and id != '" . $this->post('id') . "' ") > 0) {
            $json['warn'] = lang('material.catalogEdit.repeat');
        } elseif (empty($this->post('id'))) {
            $json['warn'] = lang('material.catalogEdit.idEmpty');
        } elseif (empty($info['id'])) {
            $field = array_merge($field, ["id" => $this->post('id'), 'coid' => self::$coid]);
            $json['warn'] = insert(["table" => self::table . '_type', "field" => $field]);
        } else {
            $json['warn'] = update(["table" => self::table . '_type', "field" => $field, "where" => "id = '" . $this->post('id') . "'"]);
        }
        if (in_array($json['warn'], array("新增成功", "更新成功"))) {
            //添加日志
            $type = mb_substr($json['warn'], 0, 2, 'utf-8');
            $text = str_replace(['{{staffName}}','{{type}}','{{name}}'], [$this->control['name'],$type,$field['name']], lang('material.catalogEdit.log'));
            $this->logText(array("type" => self::page, "text" => $text));
            //提示
            $_SESSION['warn'] = $json['warn'];
            $json['warn'] = 2;
        }
        //返回
        return json_encode($json, 320);
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        $typeId = $this->post('objId') ?? null;
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    lang('warehouse.searchHtml.orderNo') => text(array("name" => "orderNo")).
                        hidden(array('name' => 'typeId', 'value' => $typeId)),
                    lang('warehouse.searchHtml.address')   => text(array("name" => "address")),
                    lang('warehouse.searchHtml.name') => text(array("name" => "name")),
                ],
                [
                    lang('warehouse.searchHtml.text')  => text(array("name" => "text")),
                    "状态" => select(["name" => "state", 'option' => ['启用', '停用']]),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            case 'positionSearch':
                $tr = [
                    'code'          => [
                        'name'  => "{l.warehouse.position.code}",
                        'width' => 250,
                        'sort' => 1,
                    ],
                    'name' => [
                        'name'  => "{l.warehouse.position.name}",
                        'width' => 250,
                    ],
                    'barcode'  => [
                        'name'  => "{l.warehouse.position.barcode}",
                        'width' => 300,
                        'sort' => 1,
                    ],
                    'text'  => [
                        'name'  => '{l.warehouse.position.text}',
                        'width' => 250,
                    ],
                    'updateTime'  => [
                        'name'  => '{l.warehouse.position.updateTime}',
                        'width' => 250,
                        'sort' => 1,
                    ],
                    'state'         => [
                        'name'  => '{l.warehouse.position.state}',
                        'width' => 250,
                    ]
                ];
                break;
            default:
                $tr = [
                    'orderNo'          => [
                        'name'  => "{l.warehouse.searchHtml.orderNo}",
                        'width' => 200,
                        'sort' => 1,
                    ],
                    'name' => [
                        'name'  => "{l.warehouse.searchHtml.name}",
                        'width' => 200,
                    ],
                    'selector'  => [
                        'name'  => "{l.warehouse.searchHtml.manager}",
                        'width' => 200,
                    ],
                    'address'  => [
                        'name'  => '{l.warehouse.searchHtml.address}',
                        'width' => 200,
                    ],
                    'text'  => [
                        'name'  => '{l.warehouse.searchHtml.text}',
                        'width' => 200,
                    ],
                    'state'         => [
                        'name'  => '{l.warehouse.searchHtml.state}',
                        'width' => 150,
                    ]
                ];
        }
        return $tr;
    }

    public function homeRight()
    {
        $typeId = $this->post('objId') ?? null;
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        $url = root . "control/adIndex.html?cla=" . self::page;
        if ($this->power(self::page, "edit") && $typeId) {
            $button .= "<span onclick=\"layer('".self::page."','edit',{typeId: '$typeId'})\" class='spanButton'>".lang('warehouse.searchHtml.new')."</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">".lang('warehouse.searchHtml.del')."</span>\n";
        }
        if ($this->power(self::page, "edit")) {
            $button .= "<span onclick=\"layer('{$this->get('cla')}','stateSwitch',{type:'启用'})\" class='spanButton'>".lang('warehouse.searchHtml.start')."</span>\n";
            $button .= "<span onclick=\"layer('{$this->get('cla')}','stateSwitch',{type:'停用'})\" class='spanButton'>".lang('warehouse.searchHtml.stop')."</span>\n";
        }
        if ($this->power(self::page, 'import')) {
            $button .="<span class='spanButton' onclick=\"layer('importTemplate','importFrame',{cla:'".self::page."'})\">导入</span>";
        }
        //返回
        return $this->search($html, layout: 'pop', toolButton: $button);
    }

    /*客户列表-查询结果*/
    public function homeSearch()
    {
        $typeId = $this->post('typeId');
        //like查询数组
        $like = array(
            "typeId" => $this->post('typeId'),//类型
            "orderNo" => $this->post('orderNo'),//单据编号
            "address" => $this->post('address'),
            "name" => $this->post('name'),
            "text" => $this->post('text'),
        );
        //全等查询数组
        $equal = array(
            "state" => $this->post('state'),//状态
            "coid" => self::$coid,
        );
        $and = "";
        if ($this->post('time')) {
            $and .= self::timeComparison($this->post('time'));
        }
        $and .= self::getWarehouseSql(); //仓库权限判断
        //获取查询结果
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'time',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
        $where = search(array("like" => $like, "=" => $equal)) . $and;
        $page = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        //获取记录
        $url = root . "control/adIndex.html?cla=" . self::page;
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = array(
                "box" => array("name" => "listId", "value" => $array['id']),
                "edit" => array("title" => lang('warehouse.searchHtml.edit'), "click" => "layer('" . self::page . "','edit',{id:'" . $array['id'] . "', typeId:'" . $typeId . "'})"),
                "detail" => array("title" => lang('warehouse.searchHtml.detail'), "click" => "newIframe('" . lang('warehouse.searchHtml.detail') . "','" . $url . "&fun=detail&id=" . $array['id'] . "')"),
            );
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'selector':
                        $row[] = checkPlanClass::showSelectorText($array['selector']);
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //控件
        $button = "";
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
        ));
        //返回
        $json['html'] = $page['hint'] . $button . "<form name='listForm'>" . $li . "</form>" . $page['button'] . clear;
        $json['html'] .= <<<efo
<script>
var typeId = '{$this->post('typeId')}'
$(document).ready(function(){
    search_left(document.getElementsByClassName('container-left-search')[0])
    //优先定位到选择分类的区域
    if (typeId !== ''){
        document.getElementsByClassName('active')[0].scrollIntoView({behavior: "smooth", block: "nearest", inline: "center"}); // 滚动到选择的分类
    }
});
</script>
efo;
        $json['html'] .= $this->tabJs();
        return json_encode($json, 320);
    }

    /**
     * 获取分类名称
     * @param $id
     * @return mixed
     */
    public static function getTypeName($id): mixed
    {
        $type = query(self::table . '_type', "id = '$id'");
        if (!empty($type['pid'])) {
            $result = self::getTypeName($type['pid']);
            $name = $result . '->' . $type['name'];
        } else {
            $name = $type['name'] ?? null;
        }
        return $name;
    }

    /**
     * 编辑页
     * @return string
     */
    public function edit()
    {
        $info = query(self::table, " id = '" . $this->post('id') . "' ");
        $materialTypeBtn = $info['id'] ? "<span class='del-row-button' onclick=\"layer('orderTag','warehouse',{})\" style='margin-left: 10px'>".lang('warehouse.searchHtml.typeSwitch')."</span>" : '';
        //表单
        $html = $this->layerEdit([
            "table" => [
                [
                    must . lang('warehouse.searchHtml.typeId')."：" => "<span id='typeName'>".self::getTypeName($info['typeId'] ?: $this->post('typeId'))."</span>" . $materialTypeBtn,
                    must . lang('warehouse.searchHtml.orderNo')."：" => text(["name" => "orderNo", 'class' => 'text', "value" => $info['orderNo']]),
                ],
                [
                    must . lang('warehouse.searchHtml.name')."" => text(["name" => "name", 'class' => 'text', "value" => $info['name']]),
                    lang('warehouse.searchHtml.address')."：" => text(["name" => "address", 'class' => 'text', "value" => $info['address']]),
                ],
                [
                    lang('warehouse.searchHtml.manager')."：" => componentClass::staffSelector($info['selector'], 'staff'),
                ],
                [
                    lang('warehouse.searchHtml.text')."：" => textarea(["name" => "text", "value" => $info['text']])
                ],
            ],
            'hidden' => hidden(['name' => 'id', 'value' => $this->post('id')]) . hidden(['name' => 'typeId', 'value' => $info['typeId'] ?: $this->post('typeId')]),
        ]);
        //返回
        return $this->layer(array("title" => L('job.button.editor').self::title, "height" => 350, "html" => $html));
    }

    /**
     * 切换分类
     */
    public function changeWarehouseType(): bool|string
    {
        $id = $this->post('id');
        $materialType = query(self::table . '_type', "id = '$id'");
        $info = query(self::table, "id = '" . $this->post('wid') . "'");
        if (empty($materialType['id'])) {
            $json['warn'] = lang('warehouse.changeWarehouseType.orderNo');
        } elseif (empty($info['id'])) {
            $json['warn'] = lang('warehouse.changeWarehouseType.address');
        } else {
            $json['warn'] = update(array('table' => self::table, "field" => ['typeId' => $id], 'where' => "id = '$info[id]'"));
            if (in_array($json['warn'], ['新增成功', '更新成功'])) {
                //添加日志
                $text = str_replace(['{{staffName}}','{{name}}','{{id}}','{{typeName}}'], [$this->control['name'],$info['name'],$id,$materialType['name']], lang('warehouse.changeWarehouseType.log'));
                $this->logText(array("type" => self::page, "text" => $text));
                $json['warn'] = 2;
                $_SESSION['warn'] = lang('warehouse.changeWarehouseType.success');
            }
        }
        return json_encode($json, 320);
    }

    public function tabJs()
    {
        return <<<eof
<script>
         function chooseMaterialType(e){
             let id = $(e).data('id');
             let name = $(e).data('name');
             $('#typeName').text(name)
             $("[name='typeId']").val(id)
             $('#orderTagWarehouse').hide()
         }
</script>
eof;

    }

    /**
     * 编辑
     * @return bool|string
     */
    public function editEdit(): bool|string
    {
        $id = $this->post('id') ?: self::getId();
        $field = [
            'typeId' => $this->post('typeId'),
            'name' => $this->post('name'),
            'orderNo' => $this->post('orderNo'),
            'address' => $this->post('address'),
            'text' => $this->post('text'),
            'selector' => $this->post('staff')[0] ?? '',//员工选择器
        ];
        $staff = componentClass::returnStaffId($field['selector']);
        $field['member'] = implode(',', $staff);
        $annotation = [
            'typeId' => lang('warehouse.searchHtml.typeId'),
            'name' => lang('warehouse.searchHtml.name'),
            'orderNo' => lang('warehouse.searchHtml.orderNo'),
        ];
        $rules = [
            'typeId' => 'required',
            'name' => 'required',
            'orderNo' => 'required',
        ];
        // 校验是否符合规则
        $vt = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
            goto resp;
        }
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = lang('warehouse.editEdit.power');
        } elseif (static::total(array('table' => self::table, 'where' => "coid = '" . self::$coid . "' and id !='$id' and orderNo = '$field[orderNo]'")) > 0) {
            $json['warn'] = lang('warehouse.editEdit.orderNoRepeat');
        } elseif (static::total(array('table' => self::table, 'where' => "coid = '" . self::$coid . "' and id !='$id' and name = '$field[name]'")) > 0) {
            $json['warn'] = lang('warehouse.editEdit.nameRepeat');
        } else {
            $where = " id = '$id' ";
            $info = query(self::table, $where);
            if (!$info['id']) {
                $field = array_merge($field, [
                    'id' => $id,
                    'coid' => self::$coid,
                    'stid' => $this->control['stid'],
                    'state' => '启用',
                ]);
                $json['warn'] = static::insert(["table" => self::table, "field" => $field]);
            } else {
                $json['warn'] = static::update([
                    "table" => self::table,
                    "field" => $field,
                    "where" => $where
                ]);
            }
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $this->createDefaultPosition($id); //创建默认仓位
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = str_replace(['{{staffName}}','{{type}}','{{id}}'], [$this->control['name'],$type,$id], lang('warehouse.editEdit.log'));
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn'] = 2;
                $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $id;
            }
        }

        resp:
        return json_encode($json, 320);
    }

    /** 创建默认仓位
     * @param $id 仓库id
     * @return bool
     */
    public function createDefaultPosition($id)
    {
        //创建默认仓位
        $warehouse_position = query("warehouse_position", " coid = '" . self::$coid . "' and orderId = '$id' and isDefault = 1 ", "id");
        $warn = false;
        if (empty($warehouse_position['id'])) {
            $field = [
                'id' => suiji(),
                'coid' => self::$coid,
                'orderId' => $id,
                'name' => lang('warehouse.createDefaultPosition.default'),
                'splitCode' => '-',
                'area' => lang('warehouse.createDefaultPosition.default'),
                'barcode' => materialClass::creatBarCode(),
                'state' => '启用',
                'isDefault' => 1,
            ];
            $userNo = codeTemplateClass::generateCode('warehousePosition',[
                'prefix' => 'P',
                'table' => "warehouse_position",
                'field' => 'code',
                'where' => " and coid = '".self::$coid."'",
            ],$field);
            $field['code'] = $userNo;
            $json['warn'] = static::insert(array(
                'table' => 'warehouse_position',
                'field' => $field,
            ));
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $warn = true;
            }
        }
        return $warn;
    }


    /*详情页*/
    public function detail(): string
    {
        $info = query(self::table, " id = '{$this->get('id')}'");
        if (empty($info['id'])) {
            $html = lang('warehouse.detail.notFind');
        } else {
            //菜单
            $data = array(
                "id" => $info['id'],
                'menu' => [
                    "detail" => lang('warehouse.detail.info'),
                    'position' => lang('warehouse.detail.position'),
                ]
            );
            $button = [];
            if ($this->power(self::page, "edit")) {
                //按钮
                $button[] = [
                    "name" => lang('warehouse.detail.edit'),
                    "type" => "弹出层",
                    "cla" => $this->get('cla'),
                    "fun" => "edit",
                    "post" => ["id" => $info['id'], "typeId" => $info['typeId']],
                    'style' => 'li-btn-blue-bg',
                ];
                $state = $info['state'] == '停用' ? '启用' : '停用';
                $button[] = [
                    "name" => $state,
                    "type" => "点击事件",
                    'title' => lang('warehouse.detail.stateSwitch'),
                    "fun" => "layer('" . $this->get('cla') . "','stateSwitch',{id:'" . $info['id'] . "',type:'{$state}'})",
                ];
            }
            if ($this->power(self::page, 'del')) {
                //按钮
                $button[] = [
                    "name" => lang('warehouse.detail.del'),
                    "type" => "弹出层",
                    "cla" => $this->get('cla'),
                    "fun" => "operate",
                    "post" => ["act" => 'del', "id" => $info['id']],
                ];
            }

            //生成表单
            $data['button'] = $this->tableShowButton($button);
            $data['html'] = $this->tableShow(array(
                "基本信息" => array(
                    array(
                        lang('warehouse.detail.typeId') => self::getTypeName($info['typeId']),
                        lang('warehouse.detail.orderNo') => $info['orderNo'],
                        lang('warehouse.detail.name') => $info['name'],
                        lang('warehouse.detail.manage') => componentClass::showSelector($info['selector']),
                    ),
                    array(
                        lang('warehouse.detail.address') => $info['address'],
                    ),
                    array(
                        lang('warehouse.detail.text') => pre($info['text']),
                    ),
                ),
                lang('warehouse.detail.sys') => array(
                    array(
                        lang('warehouse.detail.stid') => self::findStaff($info['stid']),
                        lang('warehouse.detail.time') => $info['time'],
                        lang('warehouse.detail.state') => $info['state'],
                    ),
                )
            ));
            //生成页面
            $html = $this->tab($data);
        }
        //返回
        return $html;
    }

    /**
     * 启用/停用
     */
    public function stateSwitch(): bool|string
    {
        $type = $this->post('type');
        //生成表单
        $html = $this->layerEdit(array("table" => array(
            array(
                lang('warehouse.stateSwitch.warn') => lang('warehouse.stateSwitch.text') . $type,
            ),
        ), 'hidden' => hidden(array('name' => 'type', 'value' => $type))));
        //返回
        return $this->layer(array("title" => lang('warehouse.stateSwitch.stateSwitch'), "height" => 165, "html" => $html, 'formTwo' => 'listForm'));
    }

    /**
     * 启用/停用
     */
    public function stateSwitchEdit(): bool|string
    {
        $idArr = $this->post('id') ? [$this->post('id')] : $this->post('listId');
        $state = $this->post('type');
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = lang('warehouse.stateSwitchEdit.power');
        } elseif (empty($idArr) || !is_array($idArr)) {
            $json['warn'] = lang('warehouse.stateSwitchEdit.noChoice');
        } elseif (!in_array($state, ['启用', '停用'])) {
            $json['warn'] = lang('warehouse.stateSwitchEdit.typeError');
        } else {
            $field = [
                'state' => $state,
            ];
            $json['warn'] = update(array('table' => self::table, 'field' => $field, 'where' => " id in ('" . implode("','", $idArr) . "')"));
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = str_replace(['{{staffName}}','{{type}}','{{state}}','{{id}}'], [$this->control['name'],$type,$state,implode("，", $idArr)], lang('warehouse.stateSwitchEdit.log'));
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn'] = 2;
            }
        }
        //返回
        return json_encode($json, 320);
    }

    // 操作中转
    public function operate()
    {
        $act = $this->post('act') ?? '';
        $pwd = false; // 需要密码
        $form = $power = $word = '';
        $append = [];
        switch ($act) {
            case 'delType':
                $act = 'del';
                $msg = lang('warehouse.operate.type');
                $title = self::page . 'DeleteType';
                $function = 'deleteType';
                $form = self::page . 'OperateForm';
                $power = '';
                break;
            case 'delPosition':
                $act = 'del';
                $msg = lang('warehouse.operate.position');
                $title = self::page . 'DeletePosition';
                $function = 'deletePosition';
                $form = self::page . 'OperateForm, positionForm';
                $append = [hidden(['name' => 'orderId', 'value' => $this->post['orderId']])];
                $power = '';
                break;
            default:
                $act = 'del';
                $msg = lang('warehouse.operate.archives');
                $title = self::page . 'Delete';
                $function = 'delete';
                $form = self::page . 'OperateForm, listForm';
                $power = '';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = str_replace(['{{msg}}'], [$msg], lang('warehouse.operate.warn'));
            $json = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title' => $title,
                'function' => $function,
                'form' => $form,
                'power' => $power,
                'pwd' => $pwd,
                'word' => $word,
                'append' => $append,
            ]);
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 删除分类
     * @return bool|string
     */
    public function deleteType(): bool|string
    {
        $array = $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = lang('warehouse.deleteType.power');
        } elseif (empty($array)) {
            $json['warn'] = lang('warehouse.deleteType.noChoice');
        } else {
            $text = "";
            $x = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table . '_type', " id = '$id' ");
                if (!$this->juageDel($id)) {
                    $warn = lang('warehouse.deleteType.fail');
                } else {
                    //递归删除
                    $this->deleteAll($id);
                    //返回
                    $warn = lang('warehouse.deleteType.success');
                    $x++;
                }
                $text .= str_replace(['{{id}}'], [$info['id']], lang('warehouse.deleteType.text')) . $warn . "。<br>";
            }
            //添加日志
            $text =  str_replace(['{{staffName}}'], [$this->control['name']], lang('warehouse.deleteType.log'))."<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $_SESSION['warn'] = str_replace(['{{x}}'], [$x], lang('warehouse.deleteType.warn'));
            $json['warn'] = 2;
            $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }

    private function juageDel($id): bool
    {
        $bool = true;
        $material_type = query(self::table . '_type', "pid = '$id'");
        if ($material_type['id']) {
            $bool = $this->juageDel($material_type['id']);
        }
        if (static::total(array('table' => self::table, 'where' => "typeId = '$id'")) > 0) {
            return false;
        }
        return $bool;
    }

    public function deleteAll($id)
    {
        $material_type = query(self::table . '_type', "pid = '$id'");
        if ($material_type['id']) {
            $this->deleteAll($material_type['id']);
        }
        delete(array('table' => self::table . '_type', 'where' => "id = '$id'"));
    }

    /**
     * 删除
     * @return bool|string
     */
    public function delete()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = lang('warehouse.delete.power');
        } elseif (empty($array)) {
            $json['warn'] = lang('warehouse.delete.noChoice');
        } else {
            $text = "";
            $x = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
                if ($info['state'] == '启用') {
                    $warn = lang('warehouse.delete.fail');
                } else {
                    //最后删除基本参数
                    delete(array("table" => self::table, "where" => " id = '$id' "));
                    //返回
                    $warn = lang('warehouse.delete.success');
                    $x++;
                }
                $text .= str_replace(['{{id}}'], [$info['id']], lang('warehouse.delete.text')) . $warn . "。<br>";
            }
            //添加日志
            $text = str_replace(['{{staffName}}'], [$this->control['name']], lang('warehouse.delete.log')) . "<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $_SESSION['warn'] = str_replace(['{{x}}'], [$x], lang('warehouse.delete.warn'));
            $json['warn'] = 2;
            $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }

    /*列表页-查询条件*/
    public function positionOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    lang('warehouse.position.code') => text(array("name" => "code")),
                    lang('warehouse.position.name')   => text(array("name" => "name")),
                    lang('warehouse.position.state') => text(array("name" => "state")).
                        hidden(array('name' => 'id', 'value' => $this->get('id'))),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /**
     * 库位
     */
    public function position(): bool|string
    {
        $id = $this->get('id');
        $html = $this->positionOptions(false);
        //控件
        $button = '';
        if ($this->power(self::page, "edit")) {
            //$button .= "<span class='spanButton' onclick=\"layer('" . self::page . "', 'editPosition',{orderId:'" . $id . "'})\">新增</span>\n";
            $button .= "<span class='spanButton' onclick=\"layer('" . self::page . "', 'batchPosition',{orderId:'" . $id . "'})\">".lang('warehouse.position.new')."</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {act: 'delPosition', orderId: '$id'})\">".lang('warehouse.position.del')."</span>\n";
        }
        if ($this->power(self::page, "edit")) {
            $button .= "<span onclick=\"layer('{$this->get('cla')}','positionStateSwitch',{type:'启用'})\" class='spanButton'>".lang('warehouse.position.start')."</span>\n";
            $button .= "<span onclick=\"layer('{$this->get('cla')}','positionStateSwitch',{type:'停用'})\" class='spanButton'>".lang('warehouse.position.stop')."</span>\n";
        }
        $json['html'] = $this->search($html, layout: 'pop', toolButton: $button);
        return json_encode($json, 320);
    }

    /**
     *
     * @return bool|string
     */
    public function positionSearch(): bool|string
    {
        $id = $this->post('id');
        //查询结果
        $where = " orderId = '$id'";
        $equal = [
        ];
        $like = [
            'code' => $this->post('code'),
            'name' => $this->post('name'),
            'state' => $this->post('state'),
        ];
        //生成查询语句
        $where .= search([
            "=" => $equal,
            "like" => $like,
        ]);
        //排序
        $orderBy = $this->listSort(array(
            "search" => $this->post('list_sort_key') ?: 'list',
            "sort"   => $this->post('list_sort') ?: "asc",
            "array"  => array(),
        ));
        $page = $this->page([
            "table" => 'warehouse_position',
            "where" => $where,
            "order" => $orderBy['orderBy']
        ]);
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("positionForm", "listId")
        );
        //获取记录
        foreach ($page['array'] as $array) {
            $dominate = [
                "box" => [
                    "name" => "listId",
                    "value" => $array['id']
                ],
                'edit' => ["title" => lang('warehouse.position.edit'), "click" => "layer('" . self::page . "','editPosition',{id:'" . $array['id'] . "',orderId:'" . $array['orderId'] . "'})"],
            ];
            if ($array['isDefault'] == 1){
                unset($dominate['edit']);
                unset($dominate['box']);
            }
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //控件
        $button = '';
        //生成页面
        $li = $this->li(array(
            "body"        => $body,
            "install"     => $installSearch,
            "button"      => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page"        => $page['para'],
        ));
        $json['html'] = $page['hint'] . $button . "<form name='positionForm'>" . $li . "</form>" . $page['button'];
        return json_encode($json, 320);
    }

    /**
     * 批量新增
     * @return false|string
     */
    public function batchPosition()
    {
        $id = $this->post('orderId');
        //表单
        $html = $this->layerEdit(array("table" => array(
            [
                must . lang('warehouse.batchPosition.area').'：' => text(['name' => "areaStart", 'class' => 'text']) . '至 ' . text(['name' => "areaEnd", 'class' => 'text']),
                lang('warehouse.batchPosition.row').'：' => text(['name' => "rowStart", 'class' => 'text']) . '至 ' . text(['name' => "rowEnd", 'class' => 'text']),
            ],
            [
                lang('warehouse.batchPosition.col').'：' => text(['name' => "colStart", 'class' => 'text']) . '至 ' . text(['name' => "colEnd", 'class' => 'text']),
                lang('warehouse.batchPosition.floor').'：' => text(['name' => "floorStart", 'class' => 'text']) . '至 ' . text(['name' => "floorEnd", 'class' => 'text']),
            ],
            [
                must . lang('warehouse.batchPosition.splitChar').'：' => select(array('name' => 'splitChar', 'title' => lang('warehouse.batchPosition.choice'), 'value' => '-', 'option' => explode('，', para('splitCharOption'))))
            ],
            [
                lang('warehouse.batchPosition.explain').'：' => lang('warehouse.batchPosition.explainWord')
            ]
        ), 'hidden' => hidden(array('name' => 'id', 'value' => $id))));
        //返回
        return $this->layer(array("title" => lang('warehouse.batchPosition.batch'), "height" => 300, "width" => 800, "html" => $html));
    }


    public function batchPositionEdit()
    {
        $id = $this->post('id');
        $areaStart = $this->post('areaStart');
        $areaEnd = $this->post('areaEnd');
        $rowStart = $this->post('rowStart');
        $rowEnd = $this->post('rowEnd');
        $colStart = $this->post('colStart');
        $colEnd = $this->post('colEnd');
        $floorStart = $this->post('floorStart');
        $floorEnd = $this->post('floorEnd');
        $splitChar = $this->post('splitChar');
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = lang('warehouse.batchPositionEdit.power');
        } elseif (empty($id)) {
            $json['warn'] = lang('warehouse.batchPositionEdit.notFind');
        } elseif (empty($areaStart) || empty($areaEnd)) {
            $json['warn'] = lang('warehouse.batchPositionEdit.area');
        } elseif (preg_match(self::checkChar, $areaStart) == 0 || preg_match(self::checkChar, $areaEnd) == 0) {
            $json['warn'] = lang('warehouse.batchPositionEdit.areaFormat');
        } elseif ((!empty($rowStart) && empty($rowEnd)) || (empty($rowStart) && !empty($rowEnd))) {
            $json['warn'] = lang('warehouse.batchPositionEdit.row');
        } elseif ((!empty($rowStart) && preg_match(self::checkChar, $rowStart) == 0) || (!empty($rowEnd) && preg_match(self::checkChar, $rowEnd) == 0)) {
            $json['warn'] = lang('warehouse.batchPositionEdit.rowFormat');
        } elseif ((!empty($colStart) && empty($colEnd)) || (empty($colStart) && !empty($colEnd))) {
            $json['warn'] = lang('warehouse.batchPositionEdit.col');
        } elseif ((!empty($colStart) && preg_match(self::checkChar, $colStart) == 0) || (!empty($colEnd) && preg_match(self::checkChar, $colEnd) == 0)) {
            $json['warn'] = lang('warehouse.batchPositionEdit.colFormat');
        } elseif ((!empty($floorStart) && empty($floorEnd)) || (empty($floorStart) && !empty($floorEnd))) {
            $json['warn'] = lang('warehouse.batchPositionEdit.floor');
        } elseif ((!empty($floorStart) && preg_match(self::checkChar, $floorStart) == 0) || (!empty($floorEnd) && preg_match(self::checkChar, $floorEnd) == 0)) {
            $json['warn'] = lang('warehouse.batchPositionEdit.floorFormat');
        } elseif (empty($splitChar)) {
            $json['warn'] = lang('warehouse.batchPositionEdit.splitChar');
        } else {
            $areaArr = $this->combination($areaStart, $areaEnd);//区域数组
            $rowArr = $this->combination($rowStart, $rowEnd);//排数组
            $colArr = $this->combination($colStart, $colEnd);//列数组
            $floorArr = $this->combination($floorStart, $floorEnd);//层数组
            $result = [];

            foreach ($areaArr as $area) {
                $code = $area;
                if (count($rowArr) > 0) {
                    foreach ($rowArr as $row) {
                        $rowcode = $code . $splitChar . $row;

                        if (count($colArr) > 0) {
                            foreach ($colArr as $col) {
                                $colCode = $rowcode . $splitChar . $col;
                                if (count($floorArr) > 0) {
                                    foreach ($floorArr as $floor) {
                                        $result[] = $colCode . $splitChar . $floor;
                                    }
                                } else {
                                    $result[] = $colCode;
                                }
                            }
                        } else {
                            $result[] = $rowcode;
                        }
                    }
                } else {
                    $result[] = $code;
                }
            }
            if (count($result) > self::maxNum){
                $json['warn'] = str_replace(['{{maxNum}}'], [self::maxNum], lang('warehouse.batchPositionEdit.maxNum'));
            }else{
                $x = 0;
                foreach ($result as $value) {
                    $positionArr = (array)explode($splitChar, $value);
                    $field = [
                        'id' => suiji(),
                        'coid' => self::$coid,
                        'orderId' => $id,
                        'name' => $value,
                        'barcode' => materialClass::creatBarCode(),
                        'splitCode' => $splitChar,
                        'area' => $positionArr[0] ?? '',
                        'row' => $positionArr[1] ?? '',
                        'col' => $positionArr[2] ?? '',
                        'layer' => $positionArr[3] ?? '',
                    ];
                    $userNo = codeTemplateClass::generateCode('warehousePosition',[
                        'prefix' => 'P',
                        'table' => "warehouse_position",
                        'field' => 'code',
                        'where' => " and coid = '".self::$coid."'",
                    ],$field);
                    $field['code'] = $userNo;
                    if (static::total(array('table' => 'warehouse_position', 'where' => "coid = '" . self::$coid . "' and name = '" . $field['name'] . "' and orderId = '$id'")) > 0) {
                        continue;
                    }
                    $warn = static::insert(array(
                        'table' => 'warehouse_position',
                        'field' => $field,
                    ));
                    if ($warn == '新增成功') {
                        $x++;
                        $text = str_replace(['{{staffName}}','{{name}}','{{id}}'], [$this->control['name'],$value,$field['id']], lang('warehouse.batchPositionEdit.text'));
                        $this->logText(["type" => self::page, "text" => $text]);
                    }
                }
                $json['href'] = root . 'control/adIndex.html?cla=warehouse&fun=detail&menu=position&id=' . $id;
                $json['warn'] = 2;
                $_SESSION['warn'] = str_replace(['{{x}}'], [$x], lang('warehouse.batchPositionEdit.warn'));
            }

        }
        return json_encode($json, 320);
    }

    /**
     * 字母或数字组合
     */
    private function combination($start, $end): array
    {
        $result = [];
        if ($this->checkAlphabet($start) && $this->checkAlphabet($end)) {
            //都是字母时
            for ($x = ord(strtoupper($start)); $x <= ord(strtoupper($end)); $x++) {
                $result[] = chr($x);
            }
        } elseif (is_numeric($start) && is_numeric($end)) {
            for ($x = $start; $x <= $end; $x++) {
                $result[] = $x;
            }
        }
        return $result;
    }


    /**
     * 检查是否是A-Z的字母
     * @param $word
     * @return bool
     */
    private function checkAlphabet($word): bool
    {
        if (empty($word)) {
            return false;
        }
        if (preg_match("/^[A-Za-z]$/", $word) == 0) {
            return false;
        }
        return true;
    }


    /**
     * 仓位启用/停用
     */
    public function positionStateSwitch(): bool|string
    {
        $type = $this->post('type');
        //生成表单
        $html = $this->layerEdit(array("table" => array(
            array(
                lang('warehouse.positionStateSwitch.tips')."：" => lang('warehouse.positionStateSwitch.tipsWord') . $type,
            ),
        ), 'hidden' => hidden(array('name' => 'type', 'value' => $type))));
        //返回
        return $this->layer(array("title" => lang('warehouse.positionStateSwitch.stateSwitch'), "height" => 165, "html" => $html, 'formTwo' => 'positionForm'));
    }

    /**
     *  仓位启用/停用
     */
    public function positionStateSwitchEdit(): bool|string
    {
        $idArr = $this->post('listId');
        $state = $this->post('type');
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = lang('warehouse.positionStateSwitchEdit.power');
        } elseif (empty($idArr) || !is_array($idArr)) {
            $json['warn'] = lang('warehouse.positionStateSwitchEdit.noChoice');
        } elseif (!in_array($state, ['启用', '停用'])) {
            $json['warn'] = lang('warehouse.positionStateSwitchEdit.typeError');
        } else {
            $field = [
                'state' => $state,
            ];
            $text = '';
            $x = 0;
            foreach ($idArr as $id) {
                $info = query(self::table . '_position', "id = '$id'");
                $warn = update(array('table' => self::table . '_position', 'field' => $field, 'where' => " id  = '$id'"));
                if ($warn == '更新成功') {
                    $x++;
                    $text .= str_replace(['{{code}}','{{name}}','{{state}}'], [$info['code'],$info['name'],$state], lang('warehouse.positionStateSwitchEdit.text'))."<br>";
                }
            }
            if ($text) {
                //添加日志
                $text = str_replace(['{{staffName}}'], [$this->control['name']], lang('warehouse.positionStateSwitchEdit.log')). $text;
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $json['href'] = root . 'control/adIndex.html?cla=warehouse&fun=detail&menu=position&id=' . ($info['orderId'] ?? '');
            }
            $_SESSION['warn'] = str_replace(['{{x}}'], [$x], lang('warehouse.positionStateSwitchEdit.warn'));
            $json['warn'] = 2;
        }
        //返回
        return json_encode($json, 320);
    }

    public function editPosition()
    {
        $id = $this->post('id') ?: suiji();
        $info = query('warehouse_position', " id = '" . $id . "' ");
        //表单
        $html = $this->layerEdit(array("table" => array(
            [
                must . lang('warehouse.batchPosition.area').'：' => text(['name' => "area", 'class' => 'text', 'value' => $info['area']]),
                lang('warehouse.batchPosition.row').'：' => text(['name' => "row", 'class' => 'text', 'value' => $info['row']]),
            ],
            [
                lang('warehouse.batchPosition.col').'：' => text(['name' => "col", 'class' => 'text', 'value' => $info['col']]),
                lang('warehouse.batchPosition.floor').'：' => text(['name' => "layer", 'class' => 'text', 'value' => $info['layer']]),
            ],
            [
                must . lang('warehouse.batchPosition.splitChar').'：' => select(array('name' => 'splitChar', 'class' => 'width300', 'title' => '请选择', 'option' => explode('，', para('splitCharOption')), 'value' => $info['splitCode'])),
                lang('warehouse.batchPosition.barcode') => text(['name' => "barcode", 'class' => 'text', 'title' => lang('warehouse.batchPosition.auto'), 'value' => $info['barcode']]),
            ],
            [
                lang('warehouse.batchPosition.explain').'：' => lang('warehouse.batchPosition.explainWord')
            ],
            [
                lang('warehouse.batchPosition.text')."：" => textarea(["name" => "text", "value" => $info['text']])
                    . hidden(['name' => 'id', 'value' => $id]) . hidden(['name' => 'orderId', 'value' => $info['orderId'] ?: $this->post('orderId')]),
            ],
        )));
        //返回
        return $this->layer(array("title" => lang('warehouse.batchPosition.edit'), "height" => 350, "width" => 800, "html" => $html));
    }

    /*成本表基本资料新增或修改-异步处理*/
    public function editPositionEdit()
    {
        $id = $this->post('id') ?: self::getId();
        $field = [
            'orderId' => $this->post('orderId'),
            'area' => $this->post('area'),
            'row' => $this->post('row'),
            'col' => $this->post('col'),
            'layer' => $this->post('layer'),
            'splitCode' => $this->post('splitChar'),
            'barcode' => $this->post('barcode') ?: materialClass::creatBarCode(),
            'text' => $this->post('text'),
        ];
        $annotation = [
            'orderId' => lang('warehouse.editPositionEdit.orderId'),
            'area' => lang('warehouse.editPositionEdit.area'),
            'splitCode' => lang('warehouse.editPositionEdit.splitCode'),
        ];
        $rules = [
            'orderId' => 'required',
            'area' => 'required',
            'splitCode' => 'required',
        ];
        // 校验是否符合规则
        $vt = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0]; // 多个规则提示最前面一条
            goto resp;
        }
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = lang('warehouse.editPositionEdit.power');
        } elseif (!empty($field['area']) && preg_match(self::checkChar, $field['area']) == 0) {
            $json['warn'] = lang('warehouse.editPositionEdit.areaFormat');
        } elseif (!empty($field['row']) && preg_match(self::checkChar, $field['row']) == 0) {
            $json['warn'] = lang('warehouse.editPositionEdit.row');
        } elseif (!empty($field['col']) && preg_match(self::checkChar, $field['col']) == 0) {
            $json['warn'] = lang('warehouse.editPositionEdit.col');
        } elseif (!empty($field['layer']) && preg_match(self::checkChar, $field['layer']) == 0) {
            $json['warn'] = lang('warehouse.editPositionEdit.floor');
        } elseif (static::total(array('table' => 'warehouse_position', 'where' => "coid = '" . self::$coid . "' and area = '" . $field['area'] . "' and `row` = '" . $field['row'] . "' and col = '" . $field['col'] . "' and layer = '" . $field['layer'] . "' and id !='$id' and orderId = '$field[orderId]'")) > 0) {
            $json['warn'] = lang('warehouse.editPositionEdit.position');
        } else {
            $field['name'] = implode($field['splitCode'], array_filter([$this->post('area'), $this->post('row'), $this->post('col'), $this->post('layer')]));
            $table = 'warehouse_position';
            $where = " id = '$id' AND orderId = '$field[orderId]' ";
            $info = query($table, $where);
            if (!$info['id']) {
                $userNo = codeTemplateClass::generateCode('warehousePosition',[
                    'prefix' => 'P',
                    'table' => "warehouse_position",
                    'field' => 'code',
                    'where' => " and coid = '".self::$coid."'",
                ],$field);
                $field = array_merge($field, [
                    'id' => $id,
                    'coid' => self::$coid,
                    'code' => $userNo,
                    'state' => '启用',
                ]);
                $json['warn'] = static::insert(["table" => $table, "field" => $field]);
            } else {
                $json['warn'] = static::update([
                    "table" => $table,
                    "field" => $field,
                    "where" => $where,
                ]);
            }
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = str_replace(['{{staffName}}','{{type}}','{{id}}'], [$this->control['name'],$type,$id], lang('warehouse.editPositionEdit.text'));
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn'] = 2;
                $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&menu=position&id=" . $this->post('orderId');
            }
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 删除
     * @return bool|string
     */
    public function deletePosition(): bool|string
    {
        $array = $this->post('listId') ?? $this->post('id');
        $orderId = $this->post('orderId');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = lang('warehouse.deletePosition.power');
        } elseif (empty($array)) {
            $json['warn'] = lang('warehouse.deletePosition.noChoice');
        } elseif (empty($orderId)) {
            $json['warn'] = lang('warehouse.deletePosition.idEmpty');
        } else {
            $text = "";
            $x = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $where = " id = '$id'";
                $info = query("warehouse_position", $where);
                $whereIn = [
                    'warehouseId' => $info['orderId'],
                    'positionId' => $info['id'],
                    'coid' => self::$coid,
                ];
                $inventory = static::total([
                    'sql' => 'SELECT IFNULL(sum(num), 0) as total FROM `inventory_record`',
                    'where' => $whereIn,
                ]);
                if ($info['state'] != '停用') {
                    $warn = lang('warehouse.deletePosition.stop')."<br>";
                }elseif($inventory > 0){
                    $warn = lang('warehouse.deletePosition.inventory')."<br>";
                } else {
                    delete(["table" => "warehouse_position", "where" => $where]);
                    //返回
                    $warn = lang('warehouse.deletePosition.success');
                    $x++;
                }
                $text .= str_replace(['{{id}}','{{name}}'], [$info['id'],$info['name']], lang('warehouse.deletePosition.text')) . $warn . "。<br>";
            }
            //添加日志
            $text = str_replace(['{{staffName}}'], [$this->control['name']], lang('warehouse.deletePosition.log')) . "<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $_SESSION['warn'] = str_replace(['{{x}}'], [$x], lang('warehouse.deletePosition.warn'));
            $json['warn'] = 2;
            $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&menu=position&id=" . $this->post('orderId');
        }
        return json_encode($json, 320);
    }

    /**
     * 下载模板
     */
    public function downloadModel()
    {
        $templateId = $this->get('templateId');
        if (!$this->power(self::page, 'edit')) {
            $_SESSION['warn'] = lang('warehouse.downloadModel.power');
        }  else {
            $exampleData[] = ['默认分类', 'W001', '重庆仓', '重庆市', '样例数据，导入时请删除本条数据'];
            $excel    = $this->excelHead();
            $fileName = self::title.'导入模板-'.importTemplateClass::getName($templateId).'.xlsx';
            $filePath = $excel->fileName($fileName, 'sheet1');
            $format = new \Vtiful\Kernel\Format($filePath->getHandle());
            $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id:$templateId);
            $index         = 0;
            foreach ($templateField as $k => $array) {
                if ($array['display']){
                    $backgroundStyle=null;
                    if (importTemplateClass::getIsMustValue($this->importFieldInit(), $array['columnName'])){
                        //必填项判断
                        $backgroundStyle  = $format->background(
                            0xFFC04B
                        )->toResource();
                    }
                    $filePath->insertText(0, $index, $array['aliasName'],'',$backgroundStyle);
                    foreach ($exampleData as $y=>$example){
                        $exampleVal = match ($array['columnName']){
                            '分类'=>$example[0],
                            '仓库编码'=>$example[1],
                            '仓库名称'=>$example[2],
                            '仓库地址'=>$example[3],
                            '备注'=>$example[4],
                            default=>'',
                        };
                        $filePath->insertText($y+1, $index, $exampleVal);
                    }
                    $index++;
                }
            }
            $text = str_replace(['{{staffName}}'], [$this->control['name']], lang('warehouse.downloadModel.log'));
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOutPut($filePath,$fileName);
            exit(0);
        }
        header("Location:" . getenv("HTTP_REFERER"));
    }

    /*数据导入分析*/
    public function importData()
    {
        $templateId = $this->post('templateId');
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = lang('warehouse.importData.power');
        } else {
             $fomatArray = [];//导入数据格式同一为TYPE_STRING
            foreach ($this->importFieldInit() as $value){
                $fomatArray[] = \Vtiful\Kernel\Excel::TYPE_STRING;
            }
            $data = $this->importHead(format: $fomatArray);
            $x = 0;
            $text = '';
            $headArray = [];
            $row_list=0;
            foreach ($data as $i => $row) {
                $row_list++;
                if ($i==0){
                    $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id:$templateId);
                    $headArray = importTemplateClass::combinHead($templateField,$row);
                }
                if ($i > 0) {
                    $rowData = formSubArray($row);
                    //只接收模板中选中的字段的值
                    $cell = [];
                    foreach ($headArray as $index=>$headName){
                        $cell[$headName] = $rowData[$index]??'';
                    }
                    //初始化未被模板需要的字段的值
                    foreach ($this->importFieldInit() as $value){
                        $cell[$value['columnName']] = $cell[$value['columnName']]??'';
                    }
                    //多级分类分割
                    $type['id'] = '';
                    $typeArr = explode("&gt;", $cell['分类']);
                    if (is_array($typeArr)) {
                        $pid = '0';
                        foreach ($typeArr as $name) {
                            $type = query(self::table . '_type', "name = '$name' and pid = '$pid' and coid = '" . self::$coid . "'");
                            if (empty($type['id'])) {
                                $typeField = [
                                    'id' => self::getId(),
                                    'coid' => self::$coid,
                                    'pid' => $pid ?: '0',
                                    "name" => $name,      //部门名称
                                    "list" => 0,      //排序号
                                ];
                                insert(array('table' => 'warehouse_type', "field" => $typeField));
                                $pid = $typeField['id'];
                                $type['id'] = $typeField['id'];
                            } else {
                                $pid = $type['id'];
                            }
                        }
                    }
                    $field = [
                        'typeId' => $type['id'],
                        'orderNo' => $cell['仓库编码'],
                        'name' => $cell['仓库名称'],
                        'address' => $cell['仓库地址'],
                        'text' => $cell['备注'],
                    ];
                    $annotation = [
                        'typeId' => lang('warehouse.importData.typeId'),
                        'name' => lang('warehouse.importData.name'),
                        'orderNo' => lang('warehouse.importData.code'),
                    ];
                    $rules = [
                        'typeId' => 'required',
                        'name' => 'required',
                        'orderNo' => 'required',
                    ];
                    // 校验是否符合规则
                    $vt = new \verify();
                    $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
                    if ($result === false) {
                        $text .= str_replace(['{{i}}'], [$row_list], lang('warehouse.importData.errs')) . $vt->getErrs()[0] . "<br>";  // 多个规则提示最前面一条
                    } elseif (static::total(array('table' => self::table, 'where' => "coid = '" . self::$coid . "' and orderNo = '$field[orderNo]'")) > 0) {
                        $text .= str_replace(['{{i}}'], [$row_list], lang('warehouse.importData.codeRepeat'))."<br>";
                    } elseif (static::total(array('table' => self::table, 'where' => "coid = '" . self::$coid . "' and name = '$field[name]'")) > 0) {
                        $text .= str_replace(['{{i}}'], [$row_list], lang('warehouse.importData.nameRepeat')).'<br>';
                    } else {
                        $field = array_merge($field, [
                            'id' => self::getId(),
                            'coid' => self::$coid,
                            'stid' => $this->control['stid'],
                            'state' => '启用',
                        ]);
                        $warn = insert(["table" => self::table, "field" => $field]);
                        if (in_array($warn, ["新增成功", "更新成功"])) {
                            $this->createDefaultPosition($field['id']); //创建默认仓位
                            $x++;
                            $text .= str_replace(['{{i}}'], [$row_list], lang('warehouse.importData.success'))."<br>";
                        } else {
                            $text .= str_replace(['{{i}}'], [$row_list], lang('warehouse.importData.fail'))."<br>";
                        }
                    }
                }
            }
            $total = count($data)-1;
            $json['data'] = [
                'text'=>$text,
                'title'=>"您导入了{$total}条数据，成功{$x}条，失败".($total-$x)."条",
            ];
            $text = str_replace(['{{staffName}}'], [$this->control['name']], lang('warehouse.importData.log')) . $_FILES['file']['name'] . '：' . $text;
            $this->logText(["type" => self::page, "text" => $text]);
            $json['warn'] = 2;
        }
        return json_encode($json,320);
    }
    /**
     * 获取仓库名称
     * @param $id
     * @param bool $short
     * @param string $interval
     * @return mixed|string
     */
    public static function getName($id,$short = true,$interval = '-'){
        $query = query(self::table,"id = '$id'","id,orderNo,name");
        if (empty($query['id'])){
            return '';
        }
        return $short?$query['name']:$query['orderNo'].$interval.$query['name'];
    }

    /**
     * 导入模板字段初始化
     * @return array[]
     */
    public function importFieldInit($classify=''): array
    {
        return match ($classify) {
            default=>  [
                [
                    'columnName'=>'分类',
                    'aliasName'=>'分类(多级用>隔开)',

                    'isMust'=>true,
                ],
                [
                    'columnName'=>'仓库编码',
                    'aliasName'=>'仓库编码',

                    'isMust'=>true,
                    'isRepeat'=>true,
                ],
                [
                    'columnName'=>'仓库名称',
                    'aliasName'=>'仓库名称',

                    'isMust'=>true,
                    'isRepeat'=>true,
                ],
                [
                    'columnName'=>'仓库地址',
                    'aliasName'=>'仓库地址',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'备注',
                    'aliasName'=>'备注',

                    'isMust'=>false,
                ],
            ]
        };
    }
}
